#include "GameMap.h"

GameMap::GameMap(Gosu::Graphics& gfx, std::vector<bigTile> *bigTiles, std::vector<smallTile> *smallTiles) : graphics(&gfx) {



	
	loadMap("../../data/map.txt");
	

	displacementX = displacementY = 0;

	windowHeight = (AREA_MAX_Y < this->height * (int)TILESIZE)? AREA_MAX_Y / (int)TILESIZE : this->height;
	windowWidth = (AREA_MAX_X < this->width * (int)TILESIZE)? AREA_MAX_X / (int)TILESIZE : this->width;


	std::wstring filename;


	this->bigTiles = *bigTiles;
	std::vector<bigTile>::iterator it = this->bigTiles.begin();


	while(it != this->bigTiles.end()){

		filename = Gosu::sharedResourcePrefix() + Gosu::widen((*it).path);
		this->bigImages.push_back(new Gosu::Image(*graphics, filename,true));

		it++;

	}

	this->smallTiles = *smallTiles;
	std::vector<smallTile>::iterator its = this->smallTiles.begin();


	while(its != this->smallTiles.end()){

		filename = Gosu::sharedResourcePrefix() + Gosu::widen((*its).path);
		this->smallImages.push_back(new Gosu::Image(*graphics, filename,true));

		its++;

	}


	

}

PosDouble GameMap::scroll(const PosDouble &b){


	if(b.x < 5 && displacementX > 0){

		--displacementX;

	}

	if(b.x > AREA_MAX_X -5 && displacementX < width - windowWidth){

		++displacementX;

	}

	if(b.y < 5 && displacementY > 0){

		--displacementY;

	}

	if(b.y > AREA_MAX_Y - 5 && displacementY < height - windowHeight){

		++displacementY;


	}

	return PosDouble(displacementX *TILESIZE,displacementY *TILESIZE);
}


bool GameMap::onMap(const PosDouble &b){



	return (b.x > AREA_MIN_X && b.x < AREA_MAX_X &&
			b.y > AREA_MIN_Y && b.y < AREA_MAX_Y);


}


void GameMap::draw(){


	for(int i=0;i < windowWidth;i++){
		for(int j=0;j < windowHeight;j++){
			
			bigImages.at(bigGrid[i + displacementX][j + displacementY])->draw(i*TILESIZE,j*TILESIZE,1);

		}
	}

	for(int i=0;i < windowWidth * 2;i++){
		for(int j=0;j < windowHeight * 2;j++){

			if(smallGrid[i + displacementX*2][j + displacementY*2] != -1)
				smallImages.at(smallGrid[i + displacementX*2][j + displacementY*2])->draw(i*TILESIZE/2,j*TILESIZE/2,(smallTiles.at(smallGrid[i + displacementX*2][j + displacementY*2]).level == 0)? 2 : j+2);

		}
	}
}

boost::multi_array<Cell, 2> * GameMap::getAIMap(int blocksize, int &w, int &h){

	boost::multi_array<Cell, 2> * aiGrid = new boost::multi_array<Cell, 2>;
	boost::multi_array<double, 2> * tempMiniGrid = new boost::multi_array<double, 2>;

	double blockArea = (double)(blocksize * blocksize);
	aiGrid->resize(boost::extents[width*2/blocksize][height*2/blocksize]);
	tempMiniGrid->resize(boost::extents[width*2/blocksize][height*2/blocksize]);

	w = width*2/blocksize;
	h = height*2/blocksize;

	double sum = 0;
	for(int i=0;i < width * 2;i=i+blocksize){
		for(int j=0;j < height * 2;j=j+blocksize){


			for(int m=0;m < blocksize;m++){
				for(int k=0;k < blocksize;k++){

					if(m % 2 == 0 && k % 2 == 0)
						if(blocksize == 1){
							sum += bigTiles.at(bigGrid[i/2 + m/2][j/2 + k/2]).difficulty;
						}else{
							sum += bigTiles.at(bigGrid[i/2 + m/2][j/2 + k/2]).difficulty * 4;
						}

					sum += setSmallDiff(i+m,j+k);
						//sum += smallTiles.at(smallGrid[i + m][j + k]).difficulty[1];

				}
			}

			if(sum >= blockArea){
				sum = blockArea;
				(*aiGrid)[i / blocksize][j / blocksize].closed = true;

			}else{
				(*aiGrid)[i / blocksize][j / blocksize].closed = false;
			}

			(*aiGrid)[i / blocksize][j / blocksize].open = false;

			(*aiGrid)[i / blocksize][j / blocksize].totalCost = 0;
			(*aiGrid)[i / blocksize][j / blocksize].step = 0;
			(*aiGrid)[i / blocksize][j / blocksize].difficulty = sum / blockArea;
			sum = 0;

		}
	}

	saveGrid("apa.txt", aiGrid, blocksize);

	return aiGrid;

}


void GameMap::loadMap(const char * mapName){


	std::ifstream  myfile (mapName);
	if (myfile.is_open()){

		myfile >> width;
		myfile >> height;


		bigGrid.resize(boost::extents[width][height]);
		smallGrid.resize(boost::extents[width*2][height*2]);


		for(int i=0;i < height;i++){
			for(int j=0;j < width;j++){

			myfile >> bigGrid[j][i];

			}
		}

		for(int i=0;i < height*2;i++){
			for(int j=0;j < width*2;j++){

			myfile >> smallGrid[j][i];

			}
		}
		
	}

	myfile.close();


}


void GameMap::saveGrid(const char * fileName, boost::multi_array<Cell, 2> *grid, int blocksize){


	std::ofstream myfile (fileName);

	

	if (myfile.is_open()){


		for(int i=0;i < height*2 / blocksize;i++){
			for(int j=0;j < width*2 / blocksize;j++){

			myfile << (*grid)[j][i].difficulty << " ";

			}
		}



		

		myfile.close();

	}
}


double GameMap::setSmallDiff(int x, int y){


	int a = (x + 1 - MAX_TILE_SIZE > 0) ?  (x + 1- MAX_TILE_SIZE) : 0;
	int b = (y + 1- MAX_TILE_SIZE > 0) ?  (y + 1- MAX_TILE_SIZE) : 0;

	int sum = 0;

	for(int i=a;i <= x;i++){
		for(int j=b;j <= y;j++){
			
			if(smallGrid[i][j] != -1){

				sum += smallTiles.at(smallGrid[i][j]).difficulty[(y-j)*MAX_TILE_SIZE + (x-i)];

			}

		}
	}

	return sum;
}




